<template>
	<view class="nav" :style="{'height': + windowInfo.statusBarHeight + 'px'}"></view>
	<view class="crop" :style="{'border-top-width': + windowInfo.statusBarHeight + 'px'}">
		<movable-area class="area">
			<movable-view class="movable" :x="movable.x" :y="movable.y" :direction="direction" scale scale-min="0.5"
				scale-max="4" :scale-value="scale" :friction="10" out-of-bounds animation
				:style="{height: (isWHFix ? 670 : 670 / scaleWH) + 'rpx', width: (isWHFix ? 670 * scaleWH : 670) + 'rpx'}"
				@scale="onSacle" @change="onChange" @touchstart="touchStart" @touchmove="touchMove"
				@touchend="touchEnd">
				<image class="img"
					:style="{height: (isWHFix ? 670 : 670 / scaleWH) + 'rpx', width: (isWHFix ? 670 * scaleWH : 670) + 'rpx'}"
					:src="imgUrl" :mode="isWHFix ? 'heightFix' : 'widthFix'">
				</image>
			</movable-view>
		</movable-area>

		<view class="crop__top crop__aside-row"></view>
		<view class="crop__bottom crop__aside-row">
			<view class="btn">
				<button class="cancel" @click="onCancel">
					<text class="text">取消</text>
				</button>
				<button class="determine" @click="onClick">
					<text class="text">确定</text>
				</button>
			</view>
		</view>
		<view class="crop__left crop__aside-col"></view>
		<view class="crop__right crop__aside-col"></view>
		<canvas canvas-id="canvas" id="canvas"></canvas>
	</view>
</template>

<script setup>
	import {
		onLoad,
		onBackPress,
		onUnload,
	} from '@dcloudio/uni-app';
	import {
		ref,
		reactive,
		computed,
		nextTick,
		watch,
		watchEffect,
	} from 'vue';
	import {
		useUserStore,
	} from '@/stores/user';
	import {
		storeToRefs,
	} from 'pinia';
	import {
		throttle,
		debounce,
	} from '@/utils/index'

	const users = useUserStore();
	let {
		user,
	} = storeToRefs(users);
	let imgUrl = ref('');
	let isWHFix = ref(true); // true: 图片宽度比高度大，false: 图片高度比宽度大
	let scaleWH = ref(1); // true: 图片宽度与高度比例 默认：1 : 1
	let movable = reactive({
		x: 0,
		y: 0,
		top: 0,
		left: 0,
	});
	let direction = ref('none');
	let scale = ref(1);
	let touch = ref(0); // 判断是几指触摸操作，0为无触摸操作，1为1指触摸操作，2为两指触摸操作，以此类推
	let recordTouch = ref(0); // 记录 touch 的开始数
	let windowInfo = ref(uni.getWindowInfo());

	let context = uni.createCanvasContext('canvas') // 画布

	const toFixed = (num) => {
		return Math.floor(num * 100) / 100;
	}

	let scaleX = computed(() => toFixed(isWHFix.value ? uni.upx2px(670) * (scaleWH.value * scale.value - 1) :
		uni.upx2px(670) * (scale.value - 1)));
	let scaleY = computed(() => toFixed(isWHFix.value ? uni.upx2px(670) * (scale.value - 1) : uni.upx2px(
		670) * (scale.value / scaleWH.value - 1)));

	const onSacle = (e) => {
		if (touch.value === 2) {
			movable.x = e.detail.x - toFixed(uni.upx2px(isWHFix.value ? 670 * scaleWH.value : 670) * (e.detail
				.scale - 1)) / 2;
			movable.y = e.detail.y - toFixed(uni.upx2px(isWHFix.value ? 670 : 670 / scaleWH.value) * (e.detail
				.scale - 1)) / 2;
			scale.value = e.detail.scale;

			if (scale.value > 1 && direction.value != 'all') {
				direction.value = 'all';
			}
		} else if (touch.value === 0) {
			if (e.detail.scale >= 1) return;
			scale.value = e.detail.scale + 0.1;
		}
	}

	const onChange = (e) => {
		if (touch.value === 1) {
			movable.x = toFixed(e.detail.x);
			movable.y = toFixed(e.detail.y);
		} else if (touch.value === 0) {
			if (e.detail.scale < 1) return;
			if ((toFixed(e.detail.x) === 0 || toFixed(e.detail.x) === -scaleX.value) && (toFixed(e.detail.y) === 0 ||
					toFixed(e.detail.y) === -scaleY.value)) return;
			if (movable.x < -scaleX.value) {
				movable.x = -scaleX.value;
			} else if (movable.x > 0) {
				movable.x = 0;
			}

			if (movable.y < -scaleY.value) {
				movable.y = -scaleY.value;
			} else if (movable.y > 0) {
				movable.y = 0;
			}
		}
	}

	const touchStart = (e) => {
		touch.value = e.touches.length;
		recordTouch.value = e.touches.length;
	}

	const touchMove = () => {}

	const touchEnd = () => {
		touch.value !== 0 && --touch.value;
		if (touch.value !== 0) return;

		switch (recordTouch.value) {
			case 1:
				break;
			case 2:
				if (scale.value < 1) {
					scale.value = 1;
					if (scaleWH.value > 1) {
						direction.value = 'horizontal';
					} else if (scaleWH.value === 1) {
						direction.value = 'none';
					} else {
						direction.value = 'vertical';
					}
				}
				break;
			default:
				break;
		}
		recordTouch.value = 0;
	}

	const onCancel = () => {
		uni.navigateBack();
	}

	const onClick = () => {
		uni.showLoading({
			title: '正在头像上传',
			mask: true,
		});

		nextTick(() => {
			context.drawImage(imgUrl.value, movable.x, movable.y, uni.upx2px(isWHFix.value ? 670 * scaleWH
					.value : 670) * scale.value, uni.upx2px(isWHFix.value ? 670 : 670 / scaleWH.value) *
				scale.value); // 裁剪并画入画布
			context.draw(false, (e) => {
				uni.canvasToTempFilePath({
					x: 0,
					y: 0,
					width: uni.upx2px(670),
					height: uni.upx2px(670),
					canvasId: 'canvas',
					success: function(res) {
						uni.uploadFile({
							url: 'https://jyhtop.com/upload/uploadFile', //上传接口
							filePath: res.tempFilePath,
							name: 'file',
							success: (uploadFileRes) => {
								let data = null;
								if (typeof(uploadFileRes.data) == 'string') {
									data = JSON.parse(uploadFileRes.data);
								} else {
									data = uploadFileRes.data;
								}

								if (data.code == 1) {
									uni.navigateBack({
										success: () => {
											let imgUrl =
												'https://jyhtop.com/' +
												data.data.url;
											users.putUserInfo({
												imgUrl
											}).then(() => {
												uni.hideLoading();
												uni.showToast({
													title: '头像已上传',
													duration: 1000,
													position: 'bottom',
												});
											})
										}
									})
								} else {
									uni.showToast(data.message);
								}
							},
							fail: (e) => {
								uni.hideLoading();
								uni.showToast("图片上传失败，请联系开发！")
							},
							complete: function() {
								uni.hideLoading();
							}
						});
					}
				});
			});
		});

	}

	onLoad((e) => {
		imgUrl.value = e.url;

		uni.getImageInfo({
			src: e.url,
			success: (image) => {
				scaleWH.value = toFixed(image.width / image.height);
				isWHFix.value = scaleWH.value >= 1;

				if (scaleWH.value > 1) {
					movable.left = toFixed((scaleWH.value - 1) * uni.upx2px(670) / 2);
					direction.value = 'horizontal';
				} else if (scaleWH.value === 1) {
					direction.value = 'none';
				} else {
					movable.top = toFixed((1 / scaleWH.value - 1) * uni.upx2px(670) / 2);
					direction.value = 'vertical';
				}

				movable.x = -movable.left;
				movable.y = -movable.top;
			}
		});
	})

	onBackPress(() => {
		getApp().safeareaBottom('#F7F7F7');
	});
</script>

<style lang="scss" scoped>
	.nav {
		width: 100%;
		background-color: #000;
		position: absolute;
		top: 0;
		z-index: 99;
	}

	#canvas {
		width: 670rpx;
		height: 670rpx;
		position: absolute;
		z-index: -1;
	}

	.crop {
		box-sizing: border-box;
		width: 100%;
		height: 100%;
		border-style: solid;
		border-color: #000;
		background-color: #1A1A1A;
		position: relative;
		display: flex;
		justify-content: center;
		align-items: center;
		overflow: hidden;

		.area {
			width: 670rpx;
			height: 670rpx;
			background-color: #000;
			overflow: visible;
		}

		.movable {}

		&__aside-row {
			width: 100%;
			height: calc((100% - 670rpx) / 2);
			background-color: rgba(26, 26, 26, 0.5);
			position: absolute;
			z-index: 1;
		}

		&__aside-col {
			width: 40rpx;
			height: 670rpx;
			background-color: rgba(26, 26, 26, 0.5);
			position: absolute;
			z-index: 1;
		}

		&__top {
			top: 0;
		}

		&__bottom {
			bottom: 0;

			.btn {
				box-sizing: border-box;
				width: 100%;
				padding: 40rpx;
				position: absolute;
				bottom: 30px;
				display: flex;
				justify-content: space-around;

				.cancel {
					background: transparent;

					.text {
						color: #fff;
					}
				}

				.determine {
					background: #5ac725;

					.text {
						color: #fff;
					}
				}

				.uni-button:after {
					border: none;
				}
			}
		}

		&__left {
			top: calc((100% - 670rpx) / 2);
			left: 0;
		}

		&__right {
			top: calc((100% - 670rpx) / 2);
			right: 0;
		}
	}
</style>
